package dm.ast.model.gen;

import dm.ast.*;
import test.utility.Randomly;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

public class AggregateGen {
    //随机返回一个集函数
    public static DmAggregateType getRandAggregateFun(DmDataType reType,DmDataType paraType){
        List<DmAggregateType> validOptions = new ArrayList<>(Arrays.asList(DmAggregateType.values()));

        if(reType != DmDataType.INT){
            validOptions.remove(DmAggregateType.AVG);
            validOptions.remove(DmAggregateType.COUNT);
            validOptions.remove(DmAggregateType.SUM);
        }
        //sum集函数、avg集函数参数使用了字符串，导致出错，-6111：字符串转换出错
        if(paraType == DmDataType.CHAR || paraType == DmDataType.CLOB){
            validOptions.remove(DmAggregateType.AVG);
            validOptions.remove(DmAggregateType.SUM);
        }
        return Randomly.fromList(validOptions);
    }

    //随即返回一个集函数表达式
    public static DmExpression getRandAggregate(DmDataType reType  , DmExpression parameter){
        DmAggregateType aggType = getRandAggregateFun(reType,parameter.reType);
        DmExpression dmAgg = DmAggregateFun.buildDmAggregate(aggType, parameter);
        randSetDistinctFlag((DmAggregateFun)dmAgg);
        randSetStarFlag((DmAggregateFun)dmAgg);
        return dmAgg;
    }

    //boolean表达式增加集函数
    public static void modifyBoolExpWithAgg(DmBoolExpression boolExp){
        if(boolExp instanceof DmLikeExpression){
            DmLikeExpression likeExp = (DmLikeExpression) boolExp;
            if(!likeExp.getRowFlag()){
                if(Randomly.getBoolean()){
                    boolExp.setLeftExp(AggregateGen.getRandAggregate(boolExp.getLeftExp().reType , boolExp.getLeftExp()));
                }
            }
            return;
        }else if(boolExp instanceof DmInExpression){
            if(Randomly.getBoolean()){
                boolExp.setLeftExp(AggregateGen.getRandAggregate(boolExp.getLeftExp().reType , boolExp.getLeftExp()));
            }
        }else if(boolExp instanceof DmBetweenExpression){
            if(Randomly.getBoolean()){
                boolExp.setLeftExp(AggregateGen.getRandAggregate(boolExp.getLeftExp().reType , boolExp.getLeftExp()));
            }
            //MIN
            //MAX
        }else {
            if(Randomly.getBoolean()){
                boolExp.setLeftExp(AggregateGen.getRandAggregate(boolExp.getLeftExp().reType , boolExp.getLeftExp()));
            }
            if(Randomly.getBoolean()){
                if(boolExp.getRightExp() != null){
                    boolExp.setLeftExp(AggregateGen.getRandAggregate(boolExp.getRightExp().reType , boolExp.getRightExp()));
                }
            }
        }

    }

    //随机设置count(*)
    public static void randSetStarFlag(DmAggregateFun dmAgg){
        if(dmAgg.getAggregateType() == DmAggregateType.COUNT){  //count函数有几率为count(*) ,此时不能为distinct
            if(Randomly.getBoolean()){
                dmAgg.setStarFlag(true);
                dmAgg.setDistinctFlag(false);
            }else {
                dmAgg.setStarFlag(false);
            }
        }
    }

    //随机设置distinct
    public static void randSetDistinctFlag(DmAggregateFun dmAgg){
        if(Randomly.getBooleanWithSmallProbability()){
            dmAgg.setDistinctFlag(true);
        }else {
            dmAgg.setDistinctFlag(false);
        }
    }

    //随即返回一个Grouping函数表达式
    public static DmExpression getGrouping(DmExpression parameter){
        DmExpression dmAgg = DmAggregateFun.Grouping(parameter);
        return dmAgg;
    }
}
